<template>
  <li class="tree-node text-xs">
    <div v-if="nodeData.is_catalogue" class="tree-node-content flex items-center h-36px pl-12px pr-18px text-13px"
      :class="{ active: isActive }">
      <span class="tree-arrow icon cursor-pointer" :class="{ open: nodeData.open }" @click="toggleTree">
        <icon-font v-if="hasChild && hasArrow" name="arrow-down" />
      </span>
      <div class="tree-content flex-1 flex items-center justify-between" @click="setCurrent">
        <span class="node-con">{{ node.name }}</span>
        <span>
          <span v-if="isActive" class="active-tip -mr-8px inline-block flc bg-[#2D73E9] text-white rounded-8px">
            <div class="flex">
              <explaining class="w-[1em] h-[1em] -mr-1px" color="#ffffff" />
              <span class="transform scale-85">讲解中</span>
            </div>
            <!-- 正在讲解... -->
          </span>
          {{ formateTime(nodeData.time_duration) }}
        </span>
      </div>
    </div>
    <x-trans v-if="hasChild && node.open">
      <ul :class="{ 'pl-13px': node.is_catalogue }">
        <TreeNode v-for="(x, i) in node.children" :key="i" v-model:node="nodeData.children[i]" />
      </ul>
    </x-trans>
  </li>
</template>

<script
  lang="ts"
  setup
  name="TreeNode"
>
import { WritableComputedRef } from 'vue'
import { formateTime } from '@/utils/index'
const props = defineProps({
  node: {
    type: Object,
    default: () => ({}),
  },
})
const emit = defineEmits(['update:node'])

const nodeData: WritableComputedRef<LooseObject> = computed({
  get: () => props.node,
  set: (v) => emit('update:node', v),
})
const hasChild = computed(() => nodeData.value.children && nodeData.value.children.length > 0)
const hasArrow = computed(() => {
  let hasChild = false
  const fn = (arr) => {
    arr.forEach((o) => {
      if (o.is_catalogue) {
        hasChild = true
        throw hasChild
      } else if (o.children) {
        fn(o.children)
      }
    })
  }
  try {
    fn(nodeData?.value?.children || [])
    return hasChild
  } catch (e) {
    return hasChild
  }
})
const current: LooseObject = inject('current')
const nodeClick: LooseFunction = inject('nodeClick')
const getParent: LooseFunction = inject('getParent')


const isActive = computed(() => {
  const { id, is_catalogue } = current.value || {}
  // console.log(current.value, 'current')
  if (is_catalogue) return nodeData.value.id === id
  const parent: [LooseObject] = getParent()
  for (let i = parent.length - 1; i >= 0; i--) {
    if (parent[i].is_catalogue) {
      return nodeData.value.id === parent[i].id
    }
  }
  return false
})

const toggleTree = () => {
  nodeData.value = { ...nodeData.value, open: !nodeData.value.open }
}

const setCurrent = useDebounceFn(() => {
  current.value = nodeData.value
  nodeClick(nodeData.value)
}, 200)
</script>

<style scoped>
.icon {
  @apply w-1em h-1em;
  margin-right: 5px;
  font-size: 18px;
}

.tree-arrow {
  @apply transition-transform transform -rotate-90;
}

.tree-content {
  @apply whitespace-nowrap overflow-hidden overflow-ellipsis;
  /* width: calc(100% - 78px); */
  margin-right: -2px;
}

.node-con {
  @apply whitespace-nowrap overflow-hidden overflow-ellipsis;
  margin-right: -5px;
  width: calc(100% - 78px);
  line-height: 1.1
}

.tree-arrow.open {
  @apply rotate-0;
}

.active {
  @apply text-primary;
}

.tree-node-content:active {
  background-color: rgba(58, 82, 119, 0.1);
}

.active-tip {
  font-size: 12px;
  border-radius: 6px;
  padding: 4px 3px;
  line-height: 1;
  color: #ffffff;
  background-color: #2D73E9;
  transform: scale(0.6);
}
</style>
